#ifndef __IS_CORE_RAYTRACE_RAYCASTENGINE__
#define __IS_CORE_RAYTRACE_RAYCASTENGINE__

#include "../../../MCD/Core/System/LinkList.h"

namespace IS
{

/*! RayCastResult stores the hit information of a RayCast operation
*/
struct IS_CORE_API RayCastResult : public LinkListBase::Node<RayCastResult>
{
	int hit;

};	// RayCastResult

/*! IRayCastEngine defines common operations for ray-casting.
*/
class MCD_ABSTRACT_CLASS IRayCastEngine
{
public:
	virtual ~IRayCastEngine() {}

	/*! Notify the engine a new group of triangles is going to be added.
	*/
	virtual void beginTriangleGroup() = 0;

	/*! Notify the engine a new group of triangles has been added.
	*/
	virtual void endTriangleGroup() = 0;

	/*! Defines a new point.
		This must be called between beginTriangleGroup() and endTriangleGroup()
	*/
	virtual void addPoint(const Vec3f & point) = 0;

	/*! Defines a new triangle by 3 point indices.
		This must be called between beginTriangleGroup() and endTriangleGroup()
	*/
	virtual void addTriangle(size_t a, size_t b, size_t c) = 0;

	/*! Notify the engine to start batched ray-casting.
		The engine may performs any pre-computation or allocation here.
	*/
	virtual void beginRayCast() = 0;

	/*! Notify the engine to stop batched ray-casting and return a linked-list of RayCastResult.
		The engine may performs any clean up here.

		The caller is responsible for freeing the returned list.
	*/
	virtual LinkList<RayCastResult>* endRayCast() = 0;

	/*! Perform a ray-casting
		This must be called between beginRayCast() and endRayCast()
	*/
	virtual void rayCast(const Ray & ray) = 0;

};	// IRayCastEngine


/*! VoidRayCastEngine is a ray-casting engine with no functions :-)
	It acts as a framework for implementing the RayCastEngine interface.
*/
class IS_CORE_API VoidRayCastEngine : public IRayCastEngine
{
public:

	/*! Do nothing :-)
	*/
	VoidRayCastEngine();

	/*! Do nothing :-)
	*/
	sal_override ~VoidRayCastEngine();

	/*! Do nothing :-)
	*/
	sal_override void beginTriangleGroup();

	/*! Do nothing :-)
	*/
	sal_override void endTriangleGroup();

	/*! Do nothing :-)
	*/
	sal_override void addPoint(const Vec3f & point);

	/*! Do nothing :-)
	*/
	sal_override void addTriangle(size_t a, size_t b, size_t c);

	/*! Do nothing :-)
	*/
	sal_override void beginRayCast();

	/*! Do nothing :-)
	*/
	sal_override LinkList<RayCastResult>* endRayCast();

	/*! Do nothing :-)
	*/
	sal_override void rayCast(const Ray & ray);

};	// VoidRayCastEngine

}	// namespace IS

#endif	// __IS_CORE_RAYTRACE_RAYCASTENGINE__